package com.innovation.ic.b1b.monitor.base.handler;

import com.google.common.base.Strings;
import com.innovation.ic.b1b.framework.manager.RabbitMqManager;
import com.innovation.ic.b1b.monitor.base.mapper.RabbitmqAvailableJobLogMapper;
import com.innovation.ic.b1b.monitor.base.mapper.RabbitmqAvailableJobMapper;
import com.innovation.ic.b1b.monitor.base.mapper.RabbitmqMapper;
import com.innovation.ic.b1b.monitor.base.model.Rabbitmq;
import com.innovation.ic.b1b.monitor.base.model.RabbitmqAvailableJob;
import com.innovation.ic.b1b.monitor.base.model.RabbitmqAvailableJobLog;
import com.innovation.ic.b1b.monitor.base.pojo.constant.JobDataMapConstant;
import com.innovation.ic.b1b.monitor.base.pojo.enums.ActiveEnum;
import lombok.SneakyThrows;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;
import javax.annotation.Resource;
import java.sql.Date;
import java.util.Random;

/**
 * @desc   监控rabbitmq可用任务处理类
 * @author linuo
 * @time   2023年3月27日13:23:41
 */
public class RabbitmqAvailableJobHandler extends QuartzJobBean {
    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    private RabbitmqAvailableJobLogMapper rabbitmqAvailableJobLogMapper;

    @Resource
    private RabbitmqAvailableJobMapper rabbitmqAvailableJobMapper;

    @Resource
    private RabbitmqMapper rabbitmqMapper;

    @Resource
    private HandlerHelper handlerHelper;

    @SneakyThrows
    @Override
    protected void executeInternal(org.quartz.JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("开始执行监控rabbitmq可用任务");

        // 获取5-15间的随机数
        int s = getRandom(5, 15);
        int sleepTime = s * 1000;

        log.info("休眠[{}]秒", s);
        Thread.sleep(sleepTime);

        JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap();
        int id = jobDataMap.getInt(JobDataMapConstant.ID);

        RabbitmqAvailableJob rabbitmqAvailableJob = rabbitmqAvailableJobMapper.selectById(id);
        if(rabbitmqAvailableJob != null){
            Rabbitmq rabbitmq = rabbitmqMapper.selectById(rabbitmqAvailableJob.getRabbitmqId());
            if(rabbitmq != null){
                String name = rabbitmq.getName();

                // 存活状态
                Integer active = ActiveEnum.NO.getCode();

                RabbitmqAvailableJobLog rabbitmqAvailableJobLog = new RabbitmqAvailableJobLog();
                rabbitmqAvailableJobLog.setRabbitmqAvailableJobId(id);
                rabbitmqAvailableJobLog.setStartTime(new Date(System.currentTimeMillis()));

                if(Strings.isNullOrEmpty(rabbitmq.getIp()) || Strings.isNullOrEmpty(rabbitmq.getPort()) || Strings.isNullOrEmpty(rabbitmq.getUserName()) ||
                        Strings.isNullOrEmpty(rabbitmq.getPassword()) || Strings.isNullOrEmpty(rabbitmq.getVirtualHost())){
                    String message = name + "配置信息不完整,无法检测是否存活";
                    log.info(message);
                    rabbitmqAvailableJobLog.setDescription(message);
                }else{
                    // 判断rabbitmq是否可用
                    String message = judgeRabbitMqIfActive(rabbitmq);
                    if(message == null){
                        active = ActiveEnum.YES.getCode();
                    }else{
                        rabbitmqAvailableJobLog.setDescription(message);
                    }
                }

                rabbitmqAvailableJobLog.setActive(active);
                int insert = rabbitmqAvailableJobLogMapper.insert(rabbitmqAvailableJobLog);
                if(insert > 0){
                    log.info("rabbitmq可用任务日志插入成功");
                    if(active.intValue() == ActiveEnum.NO.getCode().intValue()){
                        // 发送邮件
                        String message = name + "出现异常，原因：" + rabbitmqAvailableJobLog.getDescription() + "，请查看RabbitMQ状态并及时进行异常处理。";
                        handlerHelper.sendEmail(rabbitmqAvailableJob.getAlarmEmail(), message, null);
                    }
                }
            }else{
                log.info("rabbitmq配置信息不存在,无法执行任务");
            }
        }else{
            log.info("监控rabbitmq可用任务id=[{}]的数据不存在,无法执行任务", id);
        }
    }

    /**
     * 判断rabbitmq是否可用
     * @param rabbitmq rabbitmq配置
     * @return 返回结果
     */
    private String judgeRabbitMqIfActive(Rabbitmq rabbitmq) throws InterruptedException {
        String message = null;
        try {
            log.info("第一次执行监控rabbitmq是否可用任务");
            RabbitMqManager rabbitMqManager = new RabbitMqManager(rabbitmq.getIp(), Integer.parseInt(rabbitmq.getPort()), rabbitmq.getUserName(), rabbitmq.getPassword(), rabbitmq.getVirtualHost());
            boolean open = rabbitMqManager.getChannel().isOpen();
            if(open){
                log.info("rabbitmq连接成功");
                rabbitMqManager.close();
            }else{
                rabbitMqManager.close();
                throw new Exception("RabbitMQ连接失败");
            }
        }catch (Exception e){
            // 获取10-30间的随机数
            int s = getRandom(10, 30);
            int sleepTime = s * 1000;

            log.warn("第一次执行监控rabbitmq是否可用任务出现问题,原因:[{}],待{}秒后重试", e.toString(), s);
            Thread.sleep(sleepTime);

            try {
                log.info("第二次执行监控rabbitmq是否可用任务");
                RabbitMqManager rabbitMqManager = new RabbitMqManager(rabbitmq.getIp(), Integer.parseInt(rabbitmq.getPort()), rabbitmq.getUserName(), rabbitmq.getPassword(), rabbitmq.getVirtualHost());
                boolean open = rabbitMqManager.getChannel().isOpen();
                if(open){
                    log.info("rabbitmq连接成功");
                    rabbitMqManager.close();
                }else{
                    rabbitMqManager.close();
                    throw new Exception("RabbitMQ连接失败");
                }
            }catch (Exception e1) {
                // 获取10-30间的随机数
                s = getRandom(10, 30);
                sleepTime = s * 1000;
                log.warn("第二次执行监控rabbitmq是否可用任务出现问题,原因:[{}],待{}秒后重试", e1.toString(), s);
                Thread.sleep(sleepTime);

                try {
                    log.info("第三次执行监控rabbitmq是否可用任务");
                    RabbitMqManager rabbitMqManager = new RabbitMqManager(rabbitmq.getIp(), Integer.parseInt(rabbitmq.getPort()), rabbitmq.getUserName(), rabbitmq.getPassword(), rabbitmq.getVirtualHost());
                    boolean open = rabbitMqManager.getChannel().isOpen();
                    if(open){
                        log.info("rabbitmq连接成功");
                        rabbitMqManager.close();
                    }else{
                        rabbitMqManager.close();
                        throw new Exception("RabbitMQ连接失败");
                    }
                }catch (Exception e2) {
                    log.warn("第三次执行监控rabbitmq是否可用任务出现问题,原因:[{}],rabbitmq连接失败", e2.toString());
                    message = e2.toString();
                }
            }
        }

        if(!Strings.isNullOrEmpty(message)){
            if(message.length() > 100){
                message = message.substring(0, 100);
            }
        }

        return message;
    }

    /**
     * 获取min到max间的随机数
     * @param min 最小值
     * @param max 最大值
     * @return 返回随机数
     */
    private int getRandom(int min, int max){
        Random random = new Random();
        return random.nextInt(max) % (max - min + 1) + min;
    }
}